﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Atom.Core;
using LitJson;
using OpenSocialPlugin.General;
using org.opensocial.client;
using org.opensocial.data;

using OpenSocialPlugin.Providers.Sites.Hi5;

namespace OpenSocialPlugin.Providers
{
    public class Hi5 : BaseSite, ISocialSite
    {
        OpenSocialClient client = new OpenSocialClient(new org.opensocial.client.Gadget 
        {
            ConsumerSecret = "",
            OutgoingConsumerKey = "",
            Container = org.opensocial.client.OpenSocialProvider.HI5
        });
        Sites.Hi5.SiteSettings settings = new global::OpenSocialPlugin.Providers.Sites.Hi5.SiteSettings();

        public Hi5()
        {
            settingForm = new Providers.Sites.Hi5.SettingControl();
            settings.Load();
            settingForm.setings = settings;
            _capabilities = new List<CapabilitiesEnum>();
            _capabilities.Add(CapabilitiesEnum.HasFriend);
            _capabilities.Add(CapabilitiesEnum.HasPhotos);
            _capabilities.Add(CapabilitiesEnum.HasOtherFriend);
            _capabilities.Add(CapabilitiesEnum.HasOtherPhotos);
        }

        #region ISite Members

      public string GetPersonInfo(OSP_Person person)
      {
        throw new NotImplementedException();
      }

      public string GetPhotoInfo(OSP_Photo photo)
      {
        throw new NotImplementedException();
      }

      public List<string> SearchNames { get { return null; } }
        public List<string> ExtrasNames { get { return null; } }

        public GeneralResponse Extras(string serchtxt, int type)
        {
            return new GeneralResponse();
        }
        public GeneralResponse Search(string serchtxt, int type)
        {
            return new GeneralResponse();
        }

        public GeneralResponse Home()
        {
            GeneralResponse res = new GeneralResponse();
            OSP_Person pers = Login();
            List<OSP_Person> list = GetFriends(pers);
            res.Response = list;
            res.Title = string.Format("Friends of {0} ({1})", pers, list.Count);
            return res;
        }

        public List<OSP_Person> GetFriends(OSP_Person person)
        {
            string ViewerId = person.Id; //"125996559"; // Hi5 random account/*
            client.ViewerId = person.Id;
            client.RpcEndpoint = null; // RPC is preferred because it supports batch requests; so set it to null to use REST

            // Retrieve stuff
            //System.Console.Out.WriteLine(c.listMethods());
            //Output(c.fetchActivities());
            var viewerRequest = OpenSocialClient.newFetchPersonRequest(ViewerId)// TODO: MySpace doesn't support '@me'
                .setFields("@all");
            viewerRequest.setCount(1000);
            var friendsRequest = OpenSocialClient.newFetchFriendsRequest(ViewerId);
                //.setCount(1000) // TODO: Not supported by Hi5
            //.setFields("photos");
            friendsRequest.setCount(500);
            Response<Person> friends;

            if (client.UseRpc) // Use batch
            {
                var response = new OpenSocialBatch() // TODO: Make REST support this behind the scene... Users should not have to write two implementations
                    .addRequest(viewerRequest, "viewerRequest")
                    .addRequest(friendsRequest, "friendsRequest")
                    .send(client);

                var viewer = response.getItemAsPerson("viewerRequest");
                friends = response.getItemAsPersonCollection("friendsRequest", client.UseRpc);
                friends.Insert(0, viewer);
            }
            else
            {
                var viewer = viewerRequest.requestObject<Person>(client);
                friends = friendsRequest.requestCollection<Person>(client);
                friends.Insert(0, viewer);
            }
            List<OSP_Person> persons = new List<OSP_Person>();
            foreach (var friend in friends)
            {
                persons.Add(To_Osd_Person(friend));

            }
            return persons;
        }

        List<OSP_Album> ISocialSite.GetAlbums(OSP_Person person)
        {
            string url = string.Format("http://api.hi5.com/rest/feed/albumlist/{0}", person.Id);
            AtomFeed feed = AtomFeed.Load(new Uri(url));
            List<OSP_Album> alb = new List<OSP_Album>();
            foreach (AtomEntry entry in feed.Entries)
            {
                OSP_Album album = new OSP_Album();
                album.OwnerId = person.Id;
                album.Title = entry.Title.Content;
                try
                {
                    Regex regexObj = new Regex("albumId=(?<album>.*)&amp;ownerId.*img src=\"(?<url>.*)\"");
                    Match matchResult = regexObj.Match(entry.Contents[0].Content);
                    album.Id = matchResult.Groups["album"].Value;
                    album.Thumb = matchResult.Groups["url"].Value;
                }
                catch 
                {
                    // Syntax error in the regular expression
                }
                alb.Add(album);
            }
            return alb;
        }

        List<OSP_Photo> ISocialSite.GetPhotos(OSP_Album album)
        {
            string url = string.Format("http://api.hi5.com/rest/feed/photos/user/{0}/albumid/{1}", album.OwnerId, album.Id);
            AtomFeed feed = AtomFeed.Load(new Uri(url));
            List<OSP_Photo> photos = new List<OSP_Photo>();
            foreach (AtomEntry entry in feed.Entries)
            {
                OSP_Photo photo = new OSP_Photo();
                photo.OwnerId = album.OwnerId;
                photo.AlbumId = album.Id;
                photo.Title = entry.Title.Content;
                foreach(AtomLink link in entry.Links)
                {
                    if (link.Type == MediaType.ImageJpeg && link.HRef.ToString().Contains("-02"))
                    {
                        photo.Url = link.HRef.ToString();
                    }
                    if (link.Type == MediaType.ImageJpeg && link.HRef.ToString().Contains("-01"))
                    {
                        photo.Thumb = link.HRef.ToString();
                    }
                }
                photos.Add(photo);
            }
            return photos;
        }

        void ISocialSite.Init()
        {
            //throw new NotImplementedException();
        }

        public OSP_Person GetPerson(string personId)
        {
            
            OSP_Person person = new OSP_Person();
            string ViewerId = personId; 
            client.ViewerId = personId;
            client.RpcEndpoint = null; // RPC is preferred because it supports batch requests; so set it to null to use REST

            // Retrieve stuff
            //System.Console.Out.WriteLine(c.listMethods());
            //Output(c.fetchActivities());
            var viewerRequest = OpenSocialClient.newFetchPersonRequest(ViewerId)// TODO: MySpace doesn't support '@me'
                .setFields("@all");
            viewerRequest.setCount(1000);

            if (client.UseRpc) // Use batch
            {
                var response = new OpenSocialBatch() // TODO: Make REST support this behind the scene... Users should not have to write two implementations
                    .addRequest(viewerRequest, "viewerRequest")
                    .send(client);

                var viewer = response.getItemAsPerson("viewerRequest");
                person = To_Osd_Person(viewer);
            }
            else
            {
                var viewer = viewerRequest.requestObject<Person>(client);
                person = To_Osd_Person(viewer);
            }
            return person;
        }

        public OSP_Person Login()
        {
            OSP_Person person = new OSP_Person();
            try
            {
                string contents = GetWebData(string.Format("http://api.hi5.com/rest/profile/lookup?email={0}", settings.User));
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(contents);
                person.Id = doc.ChildNodes[1].InnerText;
                person = GetPerson(person.Id);
            }
            catch 
            {

            }

            return person;
        }

        List<CapabilitiesEnum> _capabilities;
        public List<CapabilitiesEnum> Capabilities { get { return _capabilities; } }

        private SettingControl settingForm;
        public Control SettingForm
        {
            get
            {
                return settingForm;
            }
        }

        public override string ToString()
        {
            return "Hi5";
        }

        #endregion

    }
}
